package xyz.xtt.gateway.limit;

import java.util.Objects;

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.web.server.ServerWebExchange;

import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;
import xyz.xtt.gateway.cons.Cons;

/**
 * 预制限流
 * 
 * spring.cloud.gateway.routes[0].filters[1].name=RequestRateLimiter
 * #希望允许用户每秒执行多少请求，而不会丢弃任何请求。这是令牌桶填充的速率
 * spring.cloud.gateway.routes[0].filters[1].args.redis-rate-limiter.replenishRate=9
 * #是指令牌桶的容量，允许在一秒钟内完成的最大请求数,将此值设置为零将阻止所有请求。
 * spring.cloud.gateway.routes[0].filters[1].args.redis-rate-limiter.burstCapacity=9
 * spring.cloud.gateway.routes[0].filters[1].args.redis-rate-limiter.requestedTokens=1
 * spring.cloud.gateway.routes[0].filters[1].args.key-resolver=#{@uidKeyResolver}
 * 
 * @author huqibo
 * @date 2024/12/09
 */
@Slf4j
@Configuration
public class RequestRateLimiterConfig {
	/**
	 * ip级别
	 * 
	 * @return
	 */
	@Primary
	@Bean(name = "ipKeyResolver")
	public KeyResolver ipKeyResolver() {
		return new KeyResolver() {
			@Override
			public Mono<String> resolve(ServerWebExchange exchange) {
				String hostName = Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getHostName();
				log.info("hostName:{}", hostName);
				return Mono.just(hostName);
			}
		};
	}

	/**
	 * 平台级别
	 * 
	 * @return
	 */
	@Bean(name = "platformKeyResolver")
	public KeyResolver platformKeyResolver() {
		return new KeyResolver() {
			@Override
			public Mono<String> resolve(ServerWebExchange exchange) {
				String platform = Objects.requireNonNull(exchange.getRequest().getHeaders().getFirst(Cons.PLATFORM));
				log.info("platform:{}", platform);
				return Mono.just(platform);
			}
		};
	}

	/**
	 * 设备id
	 * 
	 * @return
	 */
	@Bean(name = "deviceIdKeyResolver")
	public KeyResolver deviceIdKeyResolver() {
		return new KeyResolver() {
			@Override
			public Mono<String> resolve(ServerWebExchange exchange) {
				String deviceId = Objects.requireNonNull(exchange.getRequest().getHeaders().getFirst(Cons.DEVICE_ID));
				log.info("deviceId:{}", deviceId);
				return Mono.just(deviceId);
			}
		};
	}

	/**
	 * 用户id
	 * 
	 * @return
	 */
	@Bean(name = "uidKeyResolver")
	public KeyResolver uidKeyResolver() {
		return new KeyResolver() {
			@Override
			public Mono<String> resolve(ServerWebExchange exchange) {
				String uid = Objects.requireNonNull(exchange.getRequest().getHeaders().getFirst(Cons.UID));
				log.info("uid:{}", uid);
				return Mono.just(uid);
			}
		};
	}
}
